跟上脚步,进入后台执行新时代
作者: Luiz Gustavo Martins, 合作伙伴开发技术推广工程师,合作伙伴 DevRel 团队
本文为 Android 电量管理 系列连载的第三篇,希望您能在阅读过程中收获设备续航方面的战略洞见和实践指导。
随着近几年来 Android 的不断发展,Google 逐步加强了对于后台执行的优化和限制。为了开发出现代化的 Android 应用,开发者需要学习如何通过最新方式来管理后台任务。
系统如何判定应用处于后台?
在理解后台执行这个概念之前,我们先来看看 Android 系统是如何定义前台应用的。当应用满足以下任意条件时,系统会判断应用处于前台:
具有一个可见的 Activity,不论该 Activity 处于 started 或是 paused 状态
具有一个前台服务
另一个前台应用已关联至该应用,不论是通过绑定到它的一个服务,还是通过使用它的一个内容提供程序。比如,当别的前台应用或者系统绑定了该应用的以下服务时,那么该应用处于前台:
输入法
壁纸服务
通知监听器
语音或文本服务
正在车内播放音乐的流媒体应用 (只适用于 Android Auto 车载娱乐系统)
前台服务:
https://developer.android.google.cn/reference/android/app/Service#startForeground(int,%20android.app.Notification)
绑定到它的一个服务:
https://developer.android.google.cn/guide/components/bound-services
内容提供程序:
https://developer.android.google.cn/guide/topics/providers/content-providers
输入法:
https://developer.android.google.cn/guide/topics/text/creating-input-method
壁纸服务:
https://developer.android.google.cn/reference/android/service/wallpaper/WallpaperService
通知监听器:
https://developer.android.google.cn/reference/android/service/notification/NotificationListenerService
语音:
https://developer.android.google.cn/reference/android/service/voice/VoiceInteractionService
文本:
https://developer.android.google.cn/reference/android/service/textservice/package-summary
如果以上条件均不满足,应用将被视为处于后台。
后台执行的相关行为变更
在后台运行应用会消耗设备的有限资源,如内存或者电池电量,进而影响用户的使用体验,比如说,后台任务可能会缩短设备的续航时间,或者在用户玩游戏、看视频或拍照时造成系统卡顿。
为了改善续航表现和用户体验,Android 在版本演进的过程中,针对后台执行进行了不同程度的限制,其中包括:
低耗电模式和应用待机模式: 如果设备未插接电源,处于空闲状态一段时间且屏幕关闭,系统会进入低耗电或者待机模式,并对应用行为施加相应限制;
后台位置限制: 对后台应用获取用户当前位置的频率进行限制;
后台服务限制: 限制应用在后台运行服务,并禁止应用通过隐藏/不可见方式调用 CPU 或网络资源;
近期新增特性及优化项: (1) 应用待机群组: 限制非活跃应用对设备资源的调用; (2) 后台限制: 当系统检测到应用出现不良行为时,系统会向用户询问是否要限制该应用在后台访问设备资源; (3) 省电助手功能优化。
低耗电模式和应用待机模式:
https://developer.android.google.cn/about/versions/marshmallow/android-6.0-changes#behavior-power
后台位置限制:
https://developer.android.google.cn/about/versions/oreo/background-location-limits
后台服务限制:
https://developer.android.google.cn/about/versions/oreo/background#services
应用待机群组:
https://developer.android.google.cn/preview/features/power#buckets
后台限制:
https://developer.android.google.cn/topic/performance/background-optimization#bg-restrict
省电助手功能优化:
https://developer.android.google.cn/about/versions/pie/power#battery-saver
使用案例及解决方案
开发者在选择后台执行工具前,首先要对应用需求和限制场景有个清晰的了解,我们建议您参照以下流程图,为应用制定最佳的后台决策:
作为 Android 推荐的后台管理工具,WorkManger 考虑了系统内的所有后台执行限制。如果您需要确保推迟的任务一定会被执行,请务必调用 WorkManager。该 API 允许您调度任务 (单次执行或循环执行) ,组合任务和构成任务链。您还可以添加任务执行的约束条件,例如:当设备空闲或充电时才可以触发,或者当内容提供程序发生变更时才可以运行。
以上传日志为例,您需要依次创建以下两个工作请求,才可以将压缩后的日志文件上传至服务器:第一步:压缩文件。在此步骤中,您可以添加约束条件 “当设备充电时,任务才可以被执行”。
第二步:向服务器上传文件。在创建此请求时,您应该添加 “需要联网”这一约束条件,指定任务仅在设备连接到有效网络时才会被触发。
单次执行:
https://developer.android.google.cn/reference/androidx/work/OneTimeWorkRequest
循环执行:
https://developer.android.google.cn/topic/libraries/architecture/workmanager/basics#recurring
组合任务和构成任务链:
https://developer.android.google.cn/topic/libraries/architecture/workmanager/advanced#chained
约束条件:
https://developer.android.google.cn/reference/androidx/work/Constraints
将任务编入队列后,WorkManager 会在约束条件满足的情况下,即当应用可以访问所需资源时,才会执行这两个任务。
WorkManger 的另一个优势在于它可以与 Android 的电量管理特性协同工作。假设某个任务的指定执行时间恰好落在低耗电模式时段内,那么 WorkManager 便会在维护窗口时段 (如果此时约束条件已满足,或设备暂时退出了低耗电模式) ,尝试运行该任务。
如果任务由外部事件触发且运行时间较长,例如同步新数据,请先使用 Firebase Cloud Messaging 通知您的应用,然后再调用 WorkManager 创建同步数据的工作请求。您可以阅读《使用 FCM 消息向用户发送通知》,获取更多详情。
如果应用需要立刻执行一个由用户发起的任务,即使用户退出应用或关闭屏幕 (如音乐/视频重放或者导航) 也不会影响任务的执行,请您使用前台服务。(我们将在下一篇连载中深度剖析该使用案例,敬请期待!)
如果您需要在某一特定时间运行一个无法被推迟的任务,且该任务会触发操作 (action) 并涉及用户交互,请调用 AlarmManager 中的 setExactAndAllowWhileIdle 方法。常见的定时任务包括:
服药提醒
电视节目开始前,向用户发送的提醒通知
维护窗口:
https://developer.android.google.cn/training/monitoring-device-state/doze-standby#understand_doze
Firebase Cloud Messaging:
https://firebase.google.cn/docs/cloud-messaging/
前台服务:
https://developer.android.google.cn/guide/components/services
AlarmManager:
https://developer.android.google.cn/reference/android/app/AlarmManager
setExactAndAllowWhileIdle:
https://developer.android.google.cn/reference/android/app/AlarmManager#setExactAndAllowWhileIdle(int,%20long,%20android.app.PendingIntent)
在触发标准闹铃后,您会有几秒钟的时间完成工作,此时应用可能无法访问网络 (例如,系统处于低耗电模式,或者应用被归入某一待机群组)。如果您必须访问网络,或者任务执行时间较久,请调用 WorkManager。每当唤醒闹钟被触发后,设备就会退出低电量模式并持有一个局部唤醒锁,而长时间持有唤醒锁会严重影响设备的续航时间。建议您通过 Google Play 管理中心提供的 Android Vitals 来监测应用是否存在过度唤醒的问题。
低耗电模式:
https://developer.android.google.cn/training/monitoring-device-state/doze-standby
唤醒:
https://developer.android.google.cn/topic/performance/vitals/wakeup
局部唤醒锁:
https://developer.android.google.cn/topic/performance/vitals/wakelock
Google Play 管理中心:
https://g.co/play/console
Android Vitals:
https://developer.android.google.cn/topic/performance/vitals/
总结:
FCM:
https://firebase.google.com/docs/cloud-messaging/
合理的后台执行策略可以帮助您开发出卓越的应用,在打造完美用户体验的同时,为设备保驾 “续” 航。如果您想进一步了解后台执行的相关讯息,请访问 Android 开发者官网。
Android 开发者官网:
https://developer.android.google.cn/guide/background/
请注意:WorkManager 目前只发布了公共预览版,您可以继续使用 JobScheduler 作为替代方案,不过和 WorkManger 相比,JobScheduler 有更多的局限。 JobScheduler 属于 Android 框架的一部分,它仅在 API ≥ 21 的系统上可用;而 WorkManager 则支持 API 14 及更高版本。
API 14:
https://developer.android.google.cn/reference/androidx/work/WorkManager
推荐阅读